home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / sos3-2.lha / src / cfe / cfe.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  49KB  |  1,779 lines

  1. /* --------------------------------------------------------------------------
  2.  * Copyright 1992 by Forschungszentrum Informatik (FZI)
  3.  *
  4.  * You can use and distribute this software under the terms of the licence
  5.  * you should have received along with this program.
  6.  * If not or if you want additional information, write to
  7.  * Forschungszentrum Informatik, "STONE", Haid-und-Neu-Strasse 10-14,
  8.  * D-7500 Karlsruhe 1, Germany.
  9.  * --------------------------------------------------------------------------
  10.  */
  11. // **************************************************************************
  12. // Module cfe                                                Juergen Uhl (ju)
  13. //
  14. // **************************************************************************
  15. // SOS schema compiler front end (cfe)
  16. // **************************************************************************
  17.  
  18. #include <stdio.h>
  19. #include <osfcn.h>
  20. #include "sys.h"
  21. #include "smg.h"
  22. #include "cfe_err.h"
  23. #include "trc_cfe.h"
  24. #include "mta_use.h"
  25.  
  26. #include "cfe_yacc.h"
  27. #include "cfe.h"
  28.  
  29. // EXPORT:
  30.  
  31. EXPORT sos_Schema_module        cfe_schema;
  32. EXPORT sos_Type_table        cfe_type_tab;
  33. EXPORT sos_Schema_type_List     cfe_types;
  34. EXPORT sos_Container        cfe_cnt;
  35.  
  36. EXPORT sos_Int             cfe_echo_flag = 0;
  37.  
  38.  
  39. // LOCAL
  40.  
  41. LOCAL sos_Unidentified_type ERROR_TYPE;
  42.  
  43. LOCAL sos_Class_type make_aux_class_type (sos_Generic_instantiation gi,
  44.                       sos_Schema_type_List type_decls);
  45. LOCAL sos_Schema_type cfe_get_void_type();
  46. LOCAL sos_Schema_type cfe_get_sos_Bool_type();
  47. LOCAL sos_Schema_type cfe_get_sos_Int_type();
  48. LOCAL sos_Schema_type cfe_get_sos_Eq_kind_type();
  49. LOCAL sos_Schema_type cfe_get_container_type();
  50. LOCAL void cfe_error (err_class ec, err_msg s, sos_String where);
  51. LOCAL void copy_offsets_and_size (sos_Class_type, sos_Class_type);
  52. LOCAL sos_Type_name subst_actual
  53.       (sos_Gen_param,
  54.        sos_Gen_param_List, sos_Type_name_List);
  55. LOCAL sos_Super_class_List subst_super_classes
  56.       (sos_Super_class_List,
  57.        sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
  58. LOCAL void subst_methods
  59.       (sos_Method_List, sos_Class_type,
  60.        sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
  61. LOCAL sos_Bool must_subst_params
  62.       (sos_Param_List,
  63.        sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
  64. LOCAL sos_Param_List subst_params
  65.       (sos_Param_List,
  66.        sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
  67. LOCAL sos_Bool must_subst_type_name
  68.       (sos_Type_name,
  69.        sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
  70. LOCAL sos_Type_name subst_type_name
  71.       (sos_Type_name,
  72.        sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
  73. LOCAL sos_Bool must_subst_type_names
  74.       (sos_Type_name_List,
  75.        sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
  76. LOCAL sos_Type_name_List subst_type_names
  77.       (sos_Type_name_List,
  78.        sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
  79.  
  80.  
  81. EXPORT void cfe_compile()
  82. {
  83.    T_PROC ("cfe_compile");
  84.    TT (cfe_H, T_ENTER);
  85.  
  86.    ERROR_TYPE = sos_Unidentified_type::create (TEMP_CONTAINER);
  87.    ERROR_TYPE.set_name (smg_String ("__error").make_String (TEMP_CONTAINER));
  88.  
  89.    yyparse();
  90.  
  91.    TT (cfe_H, T_LEAVE);
  92. }
  93.  
  94. EXPORT void cfe_init (sos_String name, sos_Imports imp)
  95. {
  96.    T_PROC ("cfe_init");
  97.    TT (cfe_H, T_ENTER);
  98.  
  99. #if ! BOOT
  100.    smg_String n = name;
  101.    if (n.equal ("knl") OR
  102.        n.equal ("agg") OR
  103.        n.equal ("dir") OR
  104.        n.equal ("mta") OR
  105.        n.equal ("cci"))
  106.       cfe_error (err_USE, err_CFE_RESERVED_SCHEMA_NAME);
  107. #endif
  108.  
  109.    sos_Schema_module sm;
  110.  
  111.    sos_String knlstr = smg_String ("knl").make_String (TEMP_CONTAINER);
  112.    if (NOT knlstr.equal (name))
  113.    {  sm = sos_Schema_module::lookup (knlstr);
  114.       if (sm == NO_OBJECT)
  115.          cfe_error (err_SYS, err_CFE_NO_KERNEL);
  116.       else if (NOT imp.is_element (sm))
  117.       {  imp.insert (1, sm);
  118.      sm.container().open (READING, WAITING);
  119.       }
  120.    }
  121.    knlstr.destroy();
  122.  
  123.    // not yet implemented:
  124.    // open imported schemas (transitively) for reading
  125.    // open depending schemas (transitively) for writing
  126.  
  127.    cfe_types = sos_Schema_type_List::create (cfe_cnt, FALSE);
  128.  
  129.    cfe_type_tab = sos_String_sos_Schema_type_Mapping::create (cfe_cnt, FALSE, TRUE);
  130.  
  131.    cfe_schema.set_has_external_types (FALSE);
  132.    cfe_schema.set_types (cfe_types);
  133.    cfe_schema.set_type_table (cfe_type_tab);
  134.  
  135. #ifdef BOOT
  136.    cfe_schema.install();
  137. #endif
  138.    TT (cfe_H, T_LEAVE);
  139. }
  140.  
  141.  
  142. LOCAL sos_Bool cfe_set_predefined_method (sos_Bool     is_local,
  143.                       sos_Class_type ct, 
  144.                           smg_String     n, 
  145.                           sos_Bool       is_static, 
  146.                           sos_Param_List pl,
  147.                           sos_Type_name  rt) 
  148. {
  149.    T_PROC ("cfe_set_predefined_method");
  150.    TT (cfe_H, T_ENTER);
  151.  
  152.    sos_Method_table mt;
  153.    sos_Method_List  ml;
  154.    sos_Method       m = sos_Method::create (cfe_cnt);
  155.    sos_Bool        already_defined;
  156.    sos_String         str = n.make_String(cfe_cnt);
  157.   
  158.    if (is_local)
  159.    {  mt = ct.get_inherited_methods();
  160.       ml = mt [str];
  161.       already_defined = (ml != NO_OBJECT);
  162.    }
  163.    else
  164.       already_defined = FALSE;
  165.  
  166.    m.set_name (str);
  167.    m.set_kind ((is_local) ? sos_PROTECTED 
  168.               : sos_PUBLIC);
  169.    m.set_is_abstract (FALSE);
  170.    m.set_is_static (is_static);
  171.    m.set_is_operator (FALSE);
  172.    m.set_is_predefined (TRUE);
  173.    m.set_generated_from (sos_Method::make (NO_OBJECT));
  174.    m.set_params (pl);
  175.    m.set_result_type (rt);
  176.    m.set_impls (sos_Method_impl_List::make (NO_OBJECT));
  177.  
  178.    if (already_defined)             // implies 'is_local == TRUE'
  179.    {  if (mt.lookup (m) == NO_OBJECT OR ml.card() > 1)
  180.      cfe_error (err_USE, err_CFE_INVALID_LOCAL_METHOD, str);
  181.       
  182.       str.destroy();
  183.       m.destroy();
  184.       agg_iterate (pl, sos_Param p)
  185.       {  p.destroy();
  186.       }
  187.       agg_iterate_end (pl, p);
  188.       pl.destroy();
  189.    }
  190.    else
  191.    {  m.set_defined_in (ct);
  192.  
  193.       cfe_append_method (ct, m);
  194.       if (is_local)
  195.      mt.lookup_or_add (m);
  196.    }
  197.  
  198.    TT (cfe_H, T_LEAVE);
  199.  
  200.    return already_defined;
  201. }
  202.  
  203. inline void cfe_set_predefined_public_method (sos_Class_type ct, 
  204.                           smg_String     n, 
  205.                           sos_Bool       is_static, 
  206.                           sos_Param_List pl,
  207.                           sos_Type_name  rt) 
  208. { cfe_set_predefined_method (FALSE,ct,n,is_static,pl,rt);
  209. }
  210.  
  211. inline sos_Bool cfe_set_predefined_local_method (sos_Class_type ct, 
  212.                              smg_String     n, 
  213.                              sos_Param_List pl,
  214.                              sos_Type_name  rt) 
  215. { return cfe_set_predefined_method (TRUE,ct,n,TRUE,pl,rt);
  216. }
  217.  
  218.  
  219. LOCAL void cfe_add_param (sos_Param_List pl, 
  220.               smg_String     n, 
  221.               sos_Type_name  tn,
  222.               sos_Expr      de)
  223. {
  224.    T_PROC ("cfe_add_param");
  225.    TT (cfe_H, T_ENTER);
  226.  
  227.    sos_Param p = sos_Param::create (cfe_cnt);
  228.  
  229.    p.set_name (n.make_String (cfe_cnt));
  230.    p.set_type_name (tn);
  231.    p.set_default_expr (de);
  232.    p.set_is_ref (FALSE);
  233.  
  234.    pl.append (p);
  235.  
  236.    TT (cfe_H, T_LEAVE);
  237. }
  238.  
  239.  
  240. LOCAL void cfe_set_predefined_methods (sos_Class_type ct)
  241. {
  242.    T_PROC ("cfe_set_predefined_methods");
  243.    TT (cfe_H, T_ENTER);
  244.  
  245.    sos_Param_List pl;
  246.  
  247.    // create
  248.    pl = sos_Param_List::create (cfe_cnt);
  249.    cfe_add_param (pl,"_ct",cfe_get_container_type(),sos_Expr::make (NO_OBJECT));
  250.    sos_Param_List tail = ct.get_create_params();
  251.    if (tail != NO_OBJECT)
  252.       pl += tail;
  253.    cfe_set_predefined_public_method (ct,"create",TRUE,pl,ct);
  254.  
  255.    // copy
  256.    pl = sos_Param_List::create (cfe_cnt);
  257.    cfe_add_param (pl,"o",ct,sos_Expr::make (NO_OBJECT));
  258.    cfe_add_param (pl,"cnt",cfe_get_container_type(),sos_Expr::make (NO_OBJECT));
  259.    cfe_set_predefined_public_method (ct,"copy",TRUE,pl,ct);
  260.  
  261.    // clone
  262.    pl = sos_Param_List::create (cfe_cnt);
  263.    cfe_add_param (pl,"o",ct,sos_Expr::make (NO_OBJECT));
  264.    cfe_add_param (pl,"cnt",cfe_get_container_type(),sos_Expr::make (NO_OBJECT));
  265.    cfe_set_predefined_public_method (ct,"clone",TRUE,pl,ct);
  266.  
  267.    // destroy
  268.    cfe_set_predefined_public_method (ct,"destroy",FALSE,
  269.                      sos_Param_List::create (cfe_cnt),
  270.                      cfe_get_void_type());
  271.  
  272.    // assign
  273.    pl = sos_Param_List::create (cfe_cnt);
  274.    cfe_add_param (pl,"source",cfe_get_object_type(),sos_Expr::make (NO_OBJECT));
  275.    cfe_set_predefined_public_method (ct,"assign",FALSE,pl,cfe_get_void_type());
  276.  
  277.    // equal
  278.    pl = sos_Param_List::create (cfe_cnt);
  279.    cfe_add_param (pl,"o",cfe_get_object_type(),sos_Expr::make (NO_OBJECT));
  280.    sos_Identifier id = sos_Identifier::create (cfe_cnt);
  281.    id.set_id (smg_String ("EQ_STRONG").make_String (cfe_cnt));
  282.    cfe_add_param (pl,"eq_kind",cfe_get_sos_Eq_kind_type(),id);
  283.    cfe_set_predefined_public_method (ct,"equal",FALSE,pl,
  284.                      cfe_get_sos_Bool_type());
  285.  
  286.    // hash_value
  287.    cfe_set_predefined_public_method (ct,"hash_value",FALSE,
  288.                      sos_Param_List::create (cfe_cnt),
  289.                      cfe_get_sos_Int_type());
  290.  
  291.    TT (cfe_H, T_LEAVE);
  292. }
  293.  
  294.  
  295. EXPORT void cfe_init_methods (sos_Class_type ct)
  296. {
  297.    T_PROC ("cfe_init_methods");
  298.    TT (cfe_H, T_ENTER);
  299.  
  300.    ct.set_methods (sos_Method_List::create (cfe_cnt, FALSE));
  301.    ct.set_comp_methods (sos_Method_List::create (cfe_cnt, FALSE));
  302.    ct.set_static_methods (sos_Method_List::create (cfe_cnt, FALSE));
  303.  
  304.    cfe_set_predefined_methods (ct);
  305.  
  306.    ct.set_has_init_comps (FALSE);
  307.  
  308.    TT (cfe_H, T_LEAVE);
  309. }
  310.  
  311.  
  312. EXPORT void cfe_complete_methods (sos_Class_type ct)
  313. {
  314.    T_PROC ("cfe_init_methods");
  315.    TT (cfe_H, T_ENTER);
  316.  
  317.    sos_Param_List pl;
  318.  
  319.    // local_assign
  320.    pl = sos_Param_List::create (cfe_cnt);
  321.    cfe_add_param (pl,"x",ct,sos_Expr::make (NO_OBJECT));
  322.    cfe_add_param (pl,"y",ct,sos_Expr::make (NO_OBJECT));
  323.    sos_Bool assign_defined 
  324.            = cfe_set_predefined_local_method (ct,"local_assign",pl,
  325.                           cfe_get_void_type());
  326.  
  327.    // local_equal
  328.    pl = sos_Param_List::create (cfe_cnt);
  329.    cfe_add_param (pl,"x",ct,sos_Expr::make (NO_OBJECT));
  330.    cfe_add_param (pl,"y",ct,sos_Expr::make (NO_OBJECT));
  331.    sos_Identifier id = sos_Identifier::create (cfe_cnt);
  332.    id.set_id (smg_String ("EQ_STRONG").make_String (cfe_cnt));
  333.    cfe_add_param (pl,"eq_kind",cfe_get_sos_Eq_kind_type(),id);
  334.    sos_Bool equal_defined
  335.            = cfe_set_predefined_local_method (ct,"local_equal",pl,
  336.                           cfe_get_sos_Bool_type());
  337.  
  338.    // local_hash_value
  339.    pl = sos_Param_List::create (cfe_cnt);
  340.    cfe_add_param (pl,"x",ct,sos_Expr::make (NO_OBJECT));
  341.    sos_Bool hash_value_defined
  342.            = cfe_set_predefined_local_method (ct,"local_hash_value",pl,
  343.                           cfe_get_sos_Int_type());
  344.  
  345.    if (assign_defined AND NOT equal_defined)
  346.       cfe_error (err_WNG, err_CFE_ASSIGN_WITHOUT_EQUAL);
  347.  
  348.    if (equal_defined AND NOT hash_value_defined)
  349.       cfe_error (err_WNG, err_CFE_EQUAL_WITHOUT_HASH);
  350.  
  351.    TT (cfe_H, T_LEAVE);
  352. }
  353.  
  354.  
  355. EXPORT void cfe_append_method (sos_Class_type ct, sos_Method m)
  356. {
  357.    T_PROC ("cfe_append_method");
  358.    TT (cfe_H, T_ENTER);
  359.  
  360.    if (m.get_is_static ())
  361.       ct.get_static_methods().append (m);
  362.    else if (m.has_type (sos_Comp_method_type))
  363.       ct.get_comp_methods().append (m);
  364.    else
  365.       ct.get_methods().append (m);
  366.  
  367.    TT (cfe_H, T_LEAVE);
  368. }
  369.  
  370. EXPORT void cfe_append_comp_methods
  371.     (sos_Class_type ct,
  372.       sos_Type_name tn, sos_String name, sos_Expr init,
  373.      sos_Method_kind kind, sos_Method_kind set_kind,
  374.      sos_Bool is_value, sos_Bool is_local,
  375.      sos_Int &offset)
  376. // Creates a new component method and append it to the appropriate
  377. // method lists
  378. {
  379.    T_PROC ("cfe_append_comp_method");
  380.    TT (cfe_H, T_ENTER);
  381.  
  382.    sos_Type bt;
  383.    sos_String str;
  384.    sos_Comp_method cm;
  385.    sos_Param_List pl;
  386.    sos_Param pa;
  387.    smg_String s;
  388.  
  389.    cm = sos_Comp_method::create (cfe_cnt);
  390.    s = smg_String ("get_") + name;
  391.    str = s.make_String (cfe_cnt);
  392.    cm.set_name (str);
  393.    cm.set_kind (kind);
  394.    cm.set_is_static (FALSE);
  395.    cm.set_is_operator (FALSE);
  396.    cm.set_is_predefined (FALSE);
  397.    cm.set_generated_from (sos_Method::make(NO_OBJECT));
  398.    cm.set_impls (sos_Method_impl_List::make (NO_OBJECT));
  399.    cm.set_defined_in (ct);
  400.    pl = sos_Param_List::create (cfe_cnt);
  401.    cm.set_params (pl);
  402.    cm.set_result_type (tn);
  403.    cm.set_init_expr (init);
  404.    cm.set_is_set (FALSE);
  405.    cm.set_is_value (is_value);
  406.    cm.set_is_local (is_local);
  407.    cm.set_offset (offset);
  408.    ct.get_comp_methods().append (cm);
  409.  
  410.    if (NOT is_value)
  411.    {  cm = sos_Comp_method::create (cfe_cnt);
  412.       s = smg_String ("set_") + name;
  413.       str = s.make_String (cfe_cnt);
  414.       cm.set_name (str);
  415.       cm.set_kind (set_kind);
  416.       cm.set_is_static (FALSE);
  417.       cm.set_is_operator (FALSE);
  418.       cm.set_is_predefined (FALSE);
  419.       cm.set_generated_from (sos_Method::make(NO_OBJECT));
  420.       cm.set_impls (sos_Method_impl_List::make (NO_OBJECT));
  421.       cm.set_defined_in (ct);
  422.       pa = sos_Param::create (cfe_cnt);
  423.       pa.set_name (sos_String::make (NO_OBJECT));
  424.       pa.set_type_name (tn);
  425.       pa.set_default_expr (sos_Expr::make (NO_OBJECT));
  426.       pa.set_is_ref (FALSE);
  427.       pl = sos_Param_List::create (cfe_cnt, FALSE);
  428.       pl.append (pa);
  429.       cm.set_params (pl);
  430.       cm.set_result_type (cfe_get_void_type());
  431.       cm.set_init_expr (init);
  432.       cm.set_is_set (TRUE);
  433.       cm.set_is_value (is_value);
  434.       cm.set_is_local (is_local);
  435.       cm.set_offset (offset);
  436.       ct.get_comp_methods().append (cm);
  437.    }
  438.  
  439.    bt = tn.make_base_type();
  440.    if (bt != NO_OBJECT AND bt.is_scalar())
  441.       offset += bt.get_object_size();
  442.    else if (is_local)
  443.       offset += SOS_OFFSET_SIZE;
  444.    else
  445.       offset += SOS_TYPED_ID_SIZE;
  446.  
  447.    TT (cfe_H, T_LEAVE);
  448. }
  449.  
  450.  
  451. LOCAL void cfe_commit_schema()
  452. // Enter the current schema module into the schema table and close/commit
  453. // the schema container together with the schema table container.
  454. {
  455.    T_PROC ("cfe_commit_schema");
  456.    TT (cfe_H, T_ENTER);
  457.  
  458. #ifndef BOOT
  459.    cfe_schema.install();
  460. #endif
  461.    cfe_cnt.close();
  462.  
  463.    TT (cfe_H, T_LEAVE);
  464. }
  465.  
  466.  
  467. LOCAL void cfe_reset_schema()
  468. // Destroy the current schema container.
  469. {
  470.    T_PROC ("cfe_reset_schema");
  471.    TT (cfe_H, T_ENTER);
  472.  
  473.    cfe_cnt.destroy();
  474.    cfe_cnt.close();
  475.  
  476.    TT (cfe_H, T_LEAVE);
  477. }
  478.  
  479.  
  480. EXPORT void cfe_finalize()
  481. {
  482.    T_PROC ("cfe_finalize");
  483.    TT (cfe_H, T_ENTER);
  484.  
  485.    cfe_schema.close_imports();
  486.    if (err_occurred (err_SYS) + err_occurred (err_USE) == 0)
  487.       cfe_commit_schema();
  488.    else
  489.       cfe_reset_schema();
  490.  
  491.    TT (cfe_H, T_LEAVE);
  492. }
  493.  
  494.  
  495. EXPORT void cfe_check_schema ()
  496. {
  497.    T_PROC ("cfe_check_schema");
  498.    TT (cfe_H, T_ENTER);
  499.  
  500.    agg_iterate_association (cfe_type_tab, sos_String name, sos_Schema_type tp)
  501.    {  if (tp.has_type (sos_Forward_class_type_type))
  502.      cfe_error (err_USE, err_CFE_NOT_DECLARED, tp.get_name());
  503.    }
  504.    agg_iterate_association_end (cfe_type_tab, name, tp);
  505.  
  506.    TT (cfe_H, T_LEAVE);
  507. }
  508.  
  509.  
  510. EXPORT void cfe_check_super_classes (sos_Class_type ct, sos_Type_name_List tnl)
  511. // Checks the correct use of super classes given in list 'tnl'. A class
  512. // specified as super class of any other class must be declared before.
  513. {
  514.    T_PROC ("cfe_check_super_classes");
  515.    TT (cfe_H, T_ENTER);
  516.  
  517.    sos_Cursor c = tnl.open_cursor();
  518.    for (sos_Bool valid = tnl.is_valid (c); valid;)
  519.    {  sos_Type_name tn = tnl.get(c);
  520.       sos_Bool error = FALSE;
  521.       if (tn.has_type (sos_Gen_param_type))
  522.       {  cfe_error (err_USE, err_CFE_UNDECL_CLASS, tn.make_type_name());
  523.      error = TRUE;
  524.       }
  525.       else
  526.       {  sos_Type bt = tn.make_base_type();
  527.      if (bt == NO_OBJECT)
  528.         error = TRUE;
  529.          else if (bt.has_type (sos_Class_type_type))
  530.          {  sos_Class_type sct = sos_Class_type::make(bt);
  531.         // check for "class A : A"
  532. #ifdef ATT
  533.             if (ct.operator==(sct))
  534. #else
  535.             if (ct == sct)
  536. #endif
  537.             {  cfe_error (err_USE, err_CFE_UNDECL_CLASS, tn.make_type_name());
  538.            error = TRUE;
  539.         }
  540.  
  541.         // check create parameters
  542.         sos_Param_List fpl = sct.get_create_params();
  543.         sos_Expr_List apl;
  544.         sos_Int fc, ac;
  545.         if (tn.has_type (sos_Type_with_params_type))
  546.         {  apl = sos_Type_with_params::make (tn).get_params();
  547.            ac = apl.card();
  548.         }
  549.         else
  550.         {  apl = sos_Expr_List::make (NO_OBJECT);
  551.            ac = 0;
  552.         }
  553.         if (fpl == NO_OBJECT)
  554.            fc = 0;
  555.         else
  556.            fc = fpl.card();
  557.         if (fc < ac)
  558.         {  cfe_error (err_USE, err_CFE_GEN_PARAM_MISMATCH,
  559.               tn.make_type_name());
  560.            error = TRUE;
  561.         }
  562.         else
  563.         {  sos_Bool has_defaults = TRUE;
  564.            for (ac++; ac <= fc; ac++)
  565.            {  if (fpl.get_nth (ac).get_default_expr() == NO_OBJECT)
  566.           {  has_defaults = FALSE;
  567.              break;
  568.           }
  569.            }
  570.            if (NOT has_defaults)
  571.            {  cfe_error (err_USE, err_CFE_GEN_PARAM_MISMATCH,
  572.                  tn.make_type_name());
  573.           error = TRUE;
  574.            }
  575.         }
  576.          }
  577.      else
  578.          {  cfe_error (err_USE, err_CFE_CLASS_EXPECTED, tn.make_type_name());
  579.         error = TRUE;
  580.      }
  581.       }
  582.  
  583.       if (error)
  584.       {  tnl.remove_at(c);
  585.      valid = tnl.is_valid(c);
  586.       }
  587.       else
  588.      valid = tnl.to_succ(c);
  589.    }
  590.    tnl.close_cursor (c);
  591. }
  592.  
  593.  
  594. LOCAL sos_Bool super_class_in_list (sos_Super_class_List scl, sos_Type tp)
  595. {
  596.    T_PROC ("super_class_in_list");
  597.    TT (cfe_H, T_ENTER);
  598.  
  599.    sos_Bool found = FALSE;
  600.  
  601.    agg_iterate (scl, sos_Super_class sc)
  602.    {  if (sc.get_super_class().identical(tp))
  603.       {  found = TRUE;
  604.      break;
  605.       }
  606.    }
  607.    agg_iterate_end (scl, sc);
  608.  
  609.    TT (cfe_H, T_LEAVE);
  610.    return found;
  611. }
  612.  
  613.  
  614. LOCAL sos_Expr_List formal_params_to_actuals (sos_Param_List fpl)
  615. {
  616.    T_PROC ("formal_params_to_actuals");
  617.    TT (cfe_H, T_ENTER);
  618.  
  619.    sos_Expr_List result;
  620.  
  621.    if (fpl == NO_OBJECT)
  622.       result = sos_Expr_List::make (NO_OBJECT);
  623.    else
  624.    {  result = sos_Expr_List::create (cfe_cnt);
  625.       agg_iterate (fpl, sos_Param fp)
  626.       {  sos_Identifier id = sos_Identifier::create (cfe_cnt);
  627.      id.set_id (fp.get_name());
  628.      result.append (id);
  629.       }
  630.       agg_iterate_end (fpl, fp);
  631.    }
  632.  
  633.    TT (cfe_H, T_LEAVE);
  634.  
  635.    return result;
  636. }
  637.  
  638.  
  639. LOCAL sos_Expr_List expand_params (sos_Expr_List original,
  640.                     sos_Param_List fpl,
  641.                     sos_Expr_List apl)
  642. // class A (f1, ..., fm) : ... C (o1, ..., on) ...
  643. // class B : ... A (a1, ..., am) ...
  644. // result : subst fi through ai in oi
  645. {
  646.    T_PROC ("expand_params");
  647.    TT (cfe_H, T_ENTER);
  648.  
  649.    sos_Expr_List result;
  650.  
  651.    if (original == NO_OBJECT || fpl == NO_OBJECT)
  652.       result = original;
  653.    else
  654.    {  result = sos_Expr_List::create (cfe_cnt);
  655.       agg_iterate (original, sos_Expr expr)
  656.       {  sos_Expr subst = expr;
  657.      if (expr.has_type (sos_Identifier_type))
  658.      {  sos_String id = sos_Identifier::make (expr).get_id();
  659.         sos_Bool av = apl != NO_OBJECT;
  660.         sos_Cursor c;
  661.         if (av)
  662.         {  c = apl.open_cursor();
  663.            av = apl.is_valid (c);
  664.         }
  665.  
  666.         agg_iterate (fpl, sos_Param fp)
  667.         {  sos_String s = fp.get_name();
  668.            if (s != NO_OBJECT AND s.equal (id))
  669.            {  if (av)
  670.              subst = apl.get(c);
  671.           else
  672.              subst = fp.get_default_expr();
  673.           break;
  674.            }
  675.            if (av) av = apl.to_succ (c);
  676.         }
  677.         agg_iterate_end (fpl, fp);
  678.         if (apl != NO_OBJECT)
  679.            apl.close_cursor (c);
  680.      }
  681.      result.append (subst);
  682.       }
  683.       agg_iterate_end (original, expr);
  684.    }
  685.  
  686.    TT (cfe_H, T_LEAVE);
  687.  
  688.    return result;
  689. }
  690.  
  691.  
  692. LOCAL void append_super_class (sos_Super_class_List scl,
  693.                    sos_Class_type ct,
  694.                    sos_Expr_List cpl)
  695. {
  696.    T_PROC ("append_super_class");
  697.    TT (cfe_H, T_ENTER);
  698.  
  699.    sos_Super_class sc = sos_Super_class::create (cfe_cnt);
  700.    sc.set_super_class (ct);
  701.    sc.set_create_params (cpl);
  702.    scl.append (sc);
  703.  
  704.    TT (cfe_H, T_LEAVE);
  705. }
  706.  
  707.  
  708. EXPORT void cfe_set_super_closure (sos_Class_type ct)
  709.    // compute super closure in prefix order using the already
  710.    // computed super closure of the super classes of ct.
  711.    // (i.e. a superclass appears always before any of its subclasses
  712.    //       in the Super_class_List)
  713. {
  714.    T_PROC ("cfe_set_super_closure");
  715.    TT (cfe_H, T_ENTER);
  716.  
  717.    sos_Param_List       fcp     = ct.get_create_params ();
  718.    sos_Type_name_List   tnl     = ct.get_super_classes();
  719.    sos_Super_class_List new_scl = sos_Super_class_List::create (cfe_cnt, FALSE);
  720.  
  721.    agg_iterate (tnl, sos_Type_name tn)
  722.    {
  723.       sos_Type bt = tn.make_base_type();
  724.       if (bt.has_type (sos_Class_type_type) AND
  725.       NOT super_class_in_list (new_scl, bt))
  726.       {
  727.          sos_Class_type       ct1  = sos_Class_type::make (bt);
  728.      sos_Super_class_List scl1 = ct1.get_super_closure();
  729.      sos_Param_List       fcp1 = ct1.get_create_params();
  730.      sos_Expr_List        acp1 = tn.create_params();
  731.  
  732.      agg_iterate (scl1, sos_Super_class sc2)
  733.      {
  734.         sos_Class_type ct2 = sc2.get_super_class();
  735.         if (NOT super_class_in_list (new_scl, ct2))
  736.         {
  737.            sos_Expr_List acp2 = sc2.get_create_params();
  738.            append_super_class (new_scl, ct2,
  739.                    expand_params (acp2, fcp1, acp1));
  740.         }
  741.      }
  742.      agg_iterate_end (scl1, sc2);
  743.       }
  744.    }
  745.    agg_iterate_end (tnl, tn);
  746.  
  747.    append_super_class (new_scl, ct, formal_params_to_actuals (fcp));
  748.      // the super_closure contains the class itself!
  749.  
  750.    ct.set_super_closure (new_scl);
  751.  
  752.    TT (cfe_H, T_LEAVE);
  753. }
  754.  
  755.  
  756. EXPORT void cfe_set_offsets_and_size (sos_Class_type ct, sos_Int os)
  757. {
  758.    T_PROC ("cfe_set_offsets_and_size");
  759.    TT (cfe_H, T_ENTER);
  760.  
  761.    ct.set_local_size (os);
  762.  
  763.    sos_Int              offset = 0;
  764.    sos_Super_class_List scl    = ct.get_super_closure();
  765.  
  766.    agg_iterate (scl, sos_Super_class sc)
  767.    {  sc.set_offset(offset);
  768.       offset += sc.get_super_class().get_local_size();
  769.    }
  770.    agg_iterate_end (scl, sc);
  771.    ct.set_object_size (offset);
  772.  
  773.    TT (cfe_H, T_LEAVE);
  774. }
  775.  
  776.  
  777. LOCAL void insert_methods (sos_Method_table mt, sos_Method_List ml)
  778. {
  779.    T_PROC ("insert_methods");
  780.    TT (cfe_M, T_ENTER);
  781.  
  782.    agg_iterate (ml, sos_Method m)
  783.    {  sos_Method m1 = mt.lookup_or_add (m);
  784. #ifdef ATT
  785.       if (m1.operator!=(m))
  786. #else
  787.       if (m1 != m)
  788. #endif
  789.      cfe_error (err_USE, err_CFE_INVALID_OVERLOADING, m.get_name());
  790.    }
  791.    agg_iterate_end (ml, m);
  792.  
  793.    TT (cfe_M, T_LEAVE);
  794. }
  795.  
  796.  
  797. LOCAL sos_Bool dominates (sos_Method m, sos_Method m1)
  798. // class of m derived from class of m1
  799. {
  800.    T_PROC ("dominates");
  801.    TT (cfe_M, T_ENTER);
  802.  
  803.    sos_Bool result = m.get_defined_in().is_derived_from_some
  804.             (m1.get_defined_in().root_class());
  805.  
  806.    TT (cfe_M, T_LEAVE);
  807.  
  808.    return result;
  809. }
  810.  
  811.  
  812. EXPORT void cfe_set_inherited_methods (sos_Class_type ct)
  813.    // This function yields all methods that are inherited from class "ct" by
  814.    // its super classes and the operators of class "ct" itself.
  815. {
  816.    T_PROC ("cfe_set_inherited_methods");
  817.    TT (cfe_H, T_ENTER);
  818.  
  819.    sos_Method_table mt = sos_Method_table::create (cfe_cnt);
  820.  
  821.    insert_methods (mt, ct.get_methods());
  822.    insert_methods (mt, ct.get_comp_methods());
  823.    insert_methods (mt, ct.get_static_methods());
  824.  
  825.    sos_Type_name_List super_classes = ct.get_super_classes();
  826.  
  827.    agg_iterate (super_classes, sos_Type_name stn)
  828.    {  sos_Class_type   super_class = sos_Class_type::make(stn.make_base_type());
  829.       sos_Method_table scmt        = super_class.get_inherited_methods();
  830.  
  831.       agg_iterate_association (scmt, sos_String name, sos_Method_List ml)
  832.       {  agg_iterate (ml, sos_Method m)
  833.          {  if (m.get_kind() != sos_PRIVATE AND NOT m.get_is_static())
  834.             {  sos_Method m1 = mt.lookup_or_add (m);
  835. #ifdef ATT
  836.                if (m1.operator!=(m))
  837. #else
  838.                if (m1 != m)
  839. #endif
  840.            {  // m1 - a different method with the same name as m found
  841.               // m1 doesn't overload m!
  842.  
  843.                   if (dominates (m1, m))
  844.           {  
  845. #ifdef ATT
  846.                      if (ct.operator== (m1.get_defined_in()))
  847. #else
  848.                      if (ct == m1.get_defined_in())
  849. #endif
  850.              {  if (m1.redefines (m))
  851.             {  if (m1.get_generated_from () == NO_OBJECT)
  852.                   m1.set_generated_from (m.get_generated_from());
  853.             }
  854.             else // m1 defined in the given class
  855.                  // and no redefinition
  856.                cfe_error (err_USE, err_CFE_INVALID_REDEFINITION,
  857.                       m.get_name());
  858.              }
  859.           }
  860.           else if (dominates (m, m1))
  861.              mt.replace_or_add (m);
  862.           else
  863.              cfe_error (err_USE, err_CFE_AMBIGUOUS_METHODS,
  864.                 m.get_name());
  865.            }
  866.             }
  867.          }
  868.      agg_iterate_end (ml, m);
  869.       }
  870.       agg_iterate_association_end (scmt, name, ml);
  871.    }
  872.    agg_iterate_end (super_classes, super_class);
  873.  
  874.    ct.set_inherited_methods (mt);
  875.  
  876.    TT (cfe_H, T_LEAVE);
  877. }
  878.  
  879.  
  880. EXPORT void cfe_set_root_name (sos_Class_type ct)
  881. {
  882.    T_PROC ("cfe_set_root_name");
  883.    TT (cfe_H, T_ENTER);
  884.  
  885.    sos_Gen_param_List gpl = ct.get_gen_params();
  886.  
  887.    if (gpl != NO_OBJECT)
  888.    {  smg_String s = "";
  889.  
  890.       agg_iterate (gpl, sos_Gen_param gp)
  891.       {  s += gp.make_type_name();
  892.      s += "_";
  893.       }
  894.       agg_iterate_end (gpl, gp);
  895.       s += ct.get_name();
  896.       sos_String rn = s.make_String (cfe_cnt);
  897.       ct.set_root_name (rn);
  898.       cfe_type_tab.insert (rn, ct);
  899.    }
  900.    else
  901.       ct.set_root_name (sos_String::make (NO_OBJECT));
  902.  
  903.    TT (cfe_H, T_LEAVE);
  904. }
  905.  
  906.  
  907. EXPORT void  cfe_check_type (sos_String t_name)
  908. // Checks multiple declarations of type names
  909. {
  910.    T_PROC ("cfe_check_type");
  911.    TT (cfe_H, T_ENTER);
  912.  
  913.    sos_Type t = cfe_schema.lookup_type (t_name);
  914.  
  915.    if (t != NO_OBJECT)
  916.       cfe_error (err_USE, err_CFE_MULTIPLE_TYPE_DECL, t_name);
  917.  
  918.    TT (cfe_H, T_LEAVE);
  919. }
  920.  
  921.  
  922. EXPORT void cfe_make_class_type (sos_String name, sos_Class_type ct)
  923. // Checks multiple declarations of type names
  924. {
  925.    T_PROC ("cfe_check_class_type");
  926.    TT (cfe_H, T_ENTER);
  927.  
  928.    sos_Type t = cfe_schema.lookup_type (name);
  929.  
  930.    if (t.has_type (sos_Forward_class_type_type))
  931.    {  sos_Forward_class_type fwt = sos_Forward_class_type::make(t);
  932.       fwt.set_complete (ct);
  933.    }
  934.    else if (t != NO_OBJECT)
  935.      cfe_error (err_USE, err_CFE_MULTIPLE_TYPE_DECL, name);
  936.  
  937.    TT (cfe_H, T_LEAVE);
  938. }
  939.  
  940.  
  941. EXPORT void cfe_check_no_generic (sos_Type_name tn)
  942. {
  943.    T_PROC ("cfe_check_no_generic");
  944.    TT (cfe_H, T_ENTER);
  945.  
  946.    if (tn.has_type (sos_Class_type_type))
  947.    {  sos_Class_type ct = sos_Class_type::make (tn);
  948.       if (ct.get_gen_params() != NO_OBJECT)
  949.      cfe_error (err_USE, err_CFE_NO_GENERIC_TYPE, ct.get_name());
  950.    }
  951.  
  952.    TT (cfe_H, T_LEAVE);
  953. }
  954.  
  955.  
  956. EXPORT void cfe_error (err_class ec, err_msg s, char* where /* = 0 */)
  957. {
  958.    T_PROC ("cfe_error");
  959.    TT (cfe_H, T_ENTER);
  960.  
  961.    smg_String line_msg = smg_String ("line ") + yylineno;
  962.  
  963.    if (where)
  964.       line_msg += smg_String(": ") + where;
  965.    
  966.    err_raise (ec, s, line_msg.make_Cstring (SMG_BORROW));
  967.  
  968.    TT (cfe_H, T_LEAVE);
  969. }
  970.  
  971.  
  972. LOCAL void cfe_error (err_class ec, err_msg s, sos_String where)
  973. {  sos_Cstring w = where.make_Cstring();
  974.    cfe_error (ec, s, w);
  975.    delete w;
  976. }
  977.  
  978.  
  979. EXPORT void cfe_import_module (sos_Imports imp, sos_String name)
  980.  
  981. // Check existence of a schema module named 'name' and append it
  982. // at the module list imp
  983.  
  984. {
  985.    T_PROC ("cfe_import_module");
  986.  
  987.    sos_Schema_module sm;
  988.  
  989.    sm = sos_Schema_module::lookup (name);
  990.    if (sm == NO_OBJECT)
  991.       cfe_error (err_USE, err_CFE_INVALID_IMPORT, name);
  992.    else
  993.       imp.append (sm);
  994. }
  995.  
  996.  
  997. EXPORT sos_Type_name cfe_lookup_type_name (sos_Class_type ct, sos_String name)
  998. {
  999.    T_PROC ("cfe_lookup_type_name");
  1000.    TT (cfe_H, T_ENTER);
  1001.  
  1002.    if (ct != NO_OBJECT)
  1003.    {  sos_Gen_param_List gpl = ct.get_gen_params();
  1004.       if (gpl != NO_OBJECT)
  1005.       {  sos_Gen_param gp = cfe_lookup_gen_params (name, gpl);
  1006.      if (gp != NO_OBJECT)
  1007.      {  TT (cfe_H, T_LEAVE);
  1008.         return gp;
  1009.      }
  1010.       }
  1011.    }
  1012.  
  1013.    sos_Schema_type tp = cfe_schema.lookup_type (name);
  1014.  
  1015.    if (NOT tp.identical (NO_OBJECT))
  1016.    {  TT (cfe_H, T_LEAVE);
  1017.       return tp;
  1018.    }
  1019.    else
  1020.    {  sos_String n = sos_String::copy (name, cfe_cnt);
  1021.       sos_Forward_class_type fw = sos_Forward_class_type::create (cfe_cnt);
  1022.       fw.set_name (n);
  1023.       fw.set_complete (sos_Class_type::make (NO_OBJECT));
  1024.       cfe_type_tab.insert (n, fw);
  1025.       cfe_types.append (fw);
  1026.       return fw;
  1027.    }
  1028. }
  1029.  
  1030.  
  1031. EXPORT sos_Type_name cfe_lookup_generic_instantiation
  1032.          (sos_String           gen_class_name,
  1033.           sos_Type_name_List   agpl,
  1034.           sos_Schema_type_List type_decls)
  1035. {
  1036.    T_PROC ("cfe_lookup_generic_instantiation");
  1037.    TT (cfe_H, T_ENTER);
  1038.  
  1039.    sos_Type t = cfe_schema.lookup_type (gen_class_name);
  1040.  
  1041.    if (t.identical (NO_OBJECT))
  1042.    {  cfe_error (err_USE, err_CFE_UNKNOWN_TYPE, gen_class_name);
  1043.       return ERROR_TYPE;
  1044.    }
  1045.    else if (t.has_type (sos_Forward_class_type_type))
  1046.    {  cfe_error (err_USE, err_CFE_UNDECL_CLASS, gen_class_name);
  1047.       return ERROR_TYPE;
  1048.    }
  1049.    else if (NOT t.has_type (sos_Class_type_type))
  1050.    {  cfe_error (err_USE, err_CFE_CLASS_EXPECTED, gen_class_name);
  1051.       return ERROR_TYPE;
  1052.    }
  1053.    else
  1054.    {  sos_Class_type gt = sos_Class_type::make(t);
  1055.       sos_Gen_param_List fgpl = gt.get_gen_params();
  1056.       if (fgpl == NO_OBJECT)
  1057.       {  cfe_error (err_USE, err_CFE_GENERIC_TYPE_EXPECTED, gen_class_name);
  1058.      return ERROR_TYPE;
  1059.       }
  1060.       else if (fgpl.card() != agpl.card())
  1061.       {  cfe_error (err_USE, err_CFE_GEN_PARAM_MISMATCH, gen_class_name);
  1062.      return ERROR_TYPE;
  1063.       }
  1064.       else
  1065.       {  sos_Generic_instantiation gi =
  1066.         sos_Generic_instantiation::create(cfe_cnt);
  1067.      gi.set_gen(gt);
  1068.      gi.set_gen_params(agpl);
  1069.      gi.set_instantiation (make_aux_class_type (gi, type_decls));
  1070.      return gi;
  1071.       }
  1072.    }
  1073. }
  1074.  
  1075.  
  1076. EXPORT void cfe_check_generic_instantiations (sos_Type_name_List tnl)
  1077. {  agg_iterate (tnl, sos_Type_name tn)
  1078.    {  if (tn.has_type (sos_Generic_instantiation_type))
  1079.       {  sos_Generic_instantiation gi = sos_Generic_instantiation::make (tn);
  1080.      sos_Type_name_List agpl = gi.get_gen_params();
  1081.      sos_Class_type gt = gi.get_gen();
  1082.      sos_Gen_param_List fgpl = gt.get_gen_params();
  1083.  
  1084.      agg_iterate_double (agpl, sos_Type_name agp,
  1085.                  fgpl, sos_Gen_param fgp, sos_Int comp)
  1086.      {  if (fgp.get_super_class() != NO_OBJECT AND
  1087.         NOT agp.make_type().is_derived_from (fgp.make_type()))
  1088.         {  smg_String s = smg_String (gt.get_name()) + "<...," +
  1089.                   agp.make_type_name() + ",...>";
  1090.            cfe_error (err_USE, err_CFE_GEN_PARAM_MISMATCH,
  1091.               s.make_Cstring (SMG_BORROW));
  1092.         }
  1093.      }
  1094.      agg_iterate_double_end (agpl, agp, fgpl, fgp, comp);
  1095.       }
  1096.    }
  1097.    agg_iterate_end (tnl, tn);
  1098. }
  1099.  
  1100.  
  1101. EXPORT sos_Gen_param cfe_lookup_gen_params (sos_String         name, 
  1102.                         sos_Gen_param_List gpl)
  1103.  
  1104. // Search for a generic parameter 'name' in the generic parameter list 'gpl'.
  1105. // Return the generic parameter found if any or NO_OBJECT otherwise.
  1106.  
  1107. {
  1108.    T_PROC ("cfe_lookup_gen_params");
  1109.    TT (cfe_H, T_ENTER);
  1110.  
  1111.    sos_Gen_param result;
  1112.    sos_Bool found = FALSE;
  1113.  
  1114.    agg_iterate (gpl, sos_Gen_param gp)
  1115.    {  if (name.equal (gp.get_name()))
  1116.       {  found = TRUE;
  1117.      result = gp;
  1118.      break;
  1119.       }
  1120.    }
  1121.    agg_iterate_end (gpl, gp);
  1122.  
  1123.    if (NOT found)
  1124.       result = sos_Gen_param::make (NO_OBJECT);
  1125.  
  1126.    TT (cfe_H, T_LEAVE; TB(found))
  1127.    return result;
  1128. }
  1129.  
  1130.  
  1131. EXPORT sos_Int cfe_enum_size (sos_Int nr_literals)
  1132. {  if (nr_literals <= 256)
  1133.       return 1;
  1134.    else if (nr_literals <= 65536)
  1135.       return 2;
  1136.    else
  1137.       cfe_error (err_USE, err_CFE_TOO_MANY_LITERALS);
  1138.       return 0;
  1139. }
  1140.  
  1141.  
  1142. LOCAL sos_String instantiation_name (sos_Generic_instantiation gi, 
  1143.                      sos_Bool                base_name)
  1144. {
  1145.    T_PROC ("instantiation_name");
  1146.    TT (cfe_M, T_ENTER);
  1147.  
  1148.    sos_Type_name_List tnl = gi.get_gen_params();
  1149.    smg_String s = "";
  1150.  
  1151.    agg_iterate (tnl, sos_Type_name tn)
  1152.    {  sos_String ts;
  1153.       if (base_name)
  1154.      ts = tn.make_base_type().make_type_name();
  1155.       else
  1156.      ts = tn.make_type_name();
  1157.       s += ts;
  1158.       s += "_";
  1159.    }
  1160.    agg_iterate_end (tnl, tn);
  1161.    s += gi.get_gen().get_name();
  1162.  
  1163.    TT (cfe_M, T_LEAVE);
  1164.  
  1165.    return s.make_String (TEMP_CONTAINER);
  1166.  
  1167. }
  1168.  
  1169.  
  1170. LOCAL sos_Class_type make_aux_class_type (sos_Generic_instantiation gi,
  1171.                       sos_Schema_type_List type_decls)
  1172.  
  1173. // Generates new class types by substituting the actual types of
  1174. // generic instantiation 'gi' within the corresponding generic class
  1175. // declaration. However, class instantiation 'gi' will be evaluated only if
  1176. // it is no universal instance, i.e. none of its actual types is a generic
  1177. // parameter. The created class types are inserted into type table
  1178. // 'cfe_type_tab', respectively appended at the list of output type declarations
  1179. // 'type_decls'. If 'gi' = C<T1,...,Tn> then a new class type with
  1180. // name T1'_..._Tn'_C is created  where Ti' is the base name of type Ti
  1181. // (i.e typedef's are evaluated (see function 'instantiation_name')).
  1182. // Note that the substitution of types Ti in the declaration of generic
  1183. // class C may lead to a recursive call of 'make_aux_class_type' due to
  1184. // the evaluation of class instances within the C-declaration.
  1185.  
  1186. {
  1187.    T_PROC ("make_aux_class_type");
  1188.    TT (cfe_M, T_ENTER);
  1189.  
  1190.    sos_Class_type aux_c;
  1191.    sos_Class_type g = gi.get_gen();
  1192.    sos_String base_name = instantiation_name (gi, TRUE);
  1193.  
  1194.    if (gi.is_universal())
  1195.       aux_c = gi.get_gen();
  1196.    else
  1197.    {  sos_Type tp = cfe_schema.lookup_type (base_name);
  1198.       if (tp == NO_OBJECT)
  1199.       {  sos_Gen_param_List gen_params = g.get_gen_params();
  1200.          sos_Type_name_List act_params = gi.get_gen_params();
  1201.          sos_String bn = sos_String::copy (base_name, cfe_cnt);
  1202.  
  1203.          aux_c = sos_Class_type::create (cfe_cnt);
  1204.          aux_c.set_generated_from (gi);
  1205.          aux_c.set_name(bn);
  1206.          aux_c.set_super_classes (subst_type_names
  1207.         (g.get_super_classes(), gen_params, act_params, type_decls));
  1208.  
  1209.          // IMPORTANT: generated class type must be inserted into the type
  1210.          //            table after(!) the evaluation of its super_classes
  1211.          //            and before(!) the replacement of the actual parameters
  1212.          //            in the body of the class
  1213.          cfe_type_tab.insert (bn, aux_c);
  1214.          type_decls.append (aux_c);
  1215.  
  1216.      if (g.get_create_params() == NO_OBJECT)
  1217.         aux_c.set_create_params (sos_Param_List::make (NO_OBJECT));
  1218.      else
  1219.      {  sos_Param_List new_pl = subst_params
  1220.            (g.get_create_params(), gen_params, act_params, type_decls);
  1221.         aux_c.set_create_params (new_pl);
  1222.      }
  1223.      cfe_set_super_closure (aux_c);
  1224.      copy_offsets_and_size (aux_c, g);
  1225.      aux_c.set_friends (subst_type_names
  1226.         (g.get_friends(), gen_params, act_params, type_decls));
  1227.      cfe_init_methods (aux_c);
  1228.          subst_methods (g.get_methods(), aux_c,
  1229.             gen_params, act_params, type_decls);
  1230.          subst_methods (g.get_comp_methods(), aux_c,
  1231.             gen_params, act_params, type_decls);
  1232.          subst_methods (g.get_static_methods(), aux_c,
  1233.             gen_params, act_params, type_decls);
  1234.      aux_c.set_has_init_comps (g.get_has_init_comps());
  1235.      cfe_set_inherited_methods (aux_c);
  1236.      cfe_complete_methods (aux_c);
  1237.       }
  1238.       else if (tp.has_type (sos_Class_type_type))
  1239.      aux_c = sos_Class_type::make (tp);
  1240.       else // error
  1241.      aux_c = sos_Class_type::make (NO_OBJECT);
  1242.    }
  1243.  
  1244.    sos_String name = instantiation_name (gi, FALSE);
  1245.    if (NOT base_name.equal (name) AND cfe_schema.lookup_type (name) == NO_OBJECT)
  1246.    {
  1247.       // In order to allow the use of 'name' in the application program
  1248.       // generate a typedef of the form "typedef base_name name;" .
  1249.       // Example:  SOS declarations
  1250.       //
  1251.       //            typedef sos_Int T;
  1252.       //            class C1<X> { ... X ... };
  1253.       //            class C2    { ... C1<T> ... }     generate
  1254.       //
  1255.       //            typedef sos_Int T;
  1256.       //            class C1 { ... sos_Object ... };
  1257.       //            class sos_Int_C { ... sos_Int ... };
  1258.       //            typedef sos_Int_C T_C; !!
  1259.       //            class C2 { ... T_C ... };
  1260.  
  1261.       sos_Typedef_type aux_td = sos_Typedef_type::create (cfe_cnt);
  1262.       sos_String n = sos_String::copy (name, cfe_cnt);
  1263.       aux_td.set_name (n);
  1264.  
  1265.       aux_td.set_type_name (aux_c);
  1266.  
  1267.       cfe_type_tab.insert (n, aux_td);
  1268.       type_decls.append (aux_td);
  1269.    }
  1270.  
  1271.    TT (cfe_M, T_LEAVE);
  1272.  
  1273.    return aux_c;
  1274. }
  1275.  
  1276.  
  1277. LOCAL void copy_offsets_and_size (sos_Class_type ct1, sos_Class_type ct2)
  1278. {
  1279.    T_PROC ("copy_offsets_and_size");
  1280.    TT (cfe_M, T_ENTER);
  1281.  
  1282.    ct1.set_local_size (ct2.get_local_size());
  1283.  
  1284.    sos_Super_class_List scl1 = ct1.get_super_closure();
  1285.    sos_Super_class_List scl2 = ct2.get_super_closure();
  1286.  
  1287.    if (scl1.card() != scl2.card())
  1288.       err_raise (err_SYS, err_CFE_SCRAMBLED_INSTANTIATION, NULL, FALSE);
  1289.  
  1290.    agg_iterate_double (scl1, sos_Super_class sc1,
  1291.                scl2, sos_Super_class sc2, sos_Int comp)
  1292.    {
  1293. #ifdef ATT
  1294.       if (sc1.get_super_class().root_class().operator!=
  1295.              (sc2.get_super_class().root_class()))
  1296. #else
  1297.       if (sc1.get_super_class().root_class() !=
  1298.              sc2.get_super_class().root_class())
  1299. #endif
  1300.      err_raise (err_SYS, err_CFE_SCRAMBLED_INSTANTIATION, NULL, FALSE);
  1301.  
  1302.       sc1.set_offset (sc2.get_offset());
  1303.    }
  1304.    agg_iterate_double_end (scl1, sc1, scl2, sc2, comp);
  1305.  
  1306.    ct1.set_object_size (ct2.get_object_size());
  1307.  
  1308.    TT (cfe_M, T_LEAVE);
  1309. }
  1310.  
  1311.  
  1312. LOCAL sos_Type_name subst_actual (sos_Gen_param      gp,
  1313.                   sos_Gen_param_List gpl,
  1314.                   sos_Type_name_List tnl)
  1315. {
  1316.    T_PROC ("subst_actual");
  1317.    TT (cfe_M, T_ENTER);
  1318.  
  1319.    sos_Type_name tn;
  1320.    sos_Bool  found = FALSE;
  1321.  
  1322.    agg_iterate_double (gpl, sos_Gen_param gp1,
  1323.                tnl, sos_Type_name tn1, sos_Int comp)
  1324.    {  if (gp.identical (gp1))
  1325.       {   tn = tn1; found = TRUE; break; }
  1326.    }
  1327.    agg_iterate_double_end (gpl, gp1, tnl, tn1, comp);
  1328.  
  1329.    if (NOT found)
  1330.    {  cfe_error (err_SYS, err_CFE_INTERNAL);
  1331.       tn = sos_Type_name::make (NO_OBJECT);
  1332.    }
  1333.  
  1334.    TT (cfe_M, T_LEAVE; TB(found));
  1335.  
  1336.    return tn;
  1337. }
  1338.  
  1339.  
  1340. LOCAL sos_Method subst_method (sos_Method old,
  1341.                    sos_Class_type aux_c,
  1342.                    sos_Gen_param_List gpl,
  1343.                    sos_Type_name_List tnl,
  1344.                    sos_Schema_type_List type_decls)
  1345. {
  1346.    T_PROC ("subst_method");
  1347.    TT (cfe_M, T_ENTER);
  1348.  
  1349.    sos_Param_List old_pl = old.get_params();
  1350.    sos_Param_List new_pl = subst_params (old_pl, gpl, tnl, type_decls);
  1351.    sos_Type_name old_tn = old.get_result_type();
  1352.    sos_Type_name new_tn = subst_type_name (old_tn, gpl, tnl, type_decls);
  1353.    sos_Method new_m;
  1354.  
  1355. #ifdef ATT
  1356.    if (new_pl.operator==(old_pl) AND new_tn.operator==(old_tn))
  1357. #else
  1358.    if (new_pl == old_pl AND new_tn == old_tn)
  1359. #endif
  1360.       new_m = old;
  1361.    else
  1362.    {  if (old.has_type (sos_Comp_method_type))
  1363.       {  sos_Comp_method cm = sos_Comp_method::make (old);
  1364.      sos_Comp_method new_cm = sos_Comp_method::create (cfe_cnt);
  1365.      new_cm.set_is_set (cm.get_is_set());
  1366.      new_cm.set_is_value (cm.get_is_value());
  1367.      new_cm.set_is_local (cm.get_is_local());
  1368.      new_cm.set_offset (cm.get_offset());
  1369.      new_m = new_cm;
  1370.       }
  1371.       else
  1372.      new_m = sos_Method::create (cfe_cnt);
  1373.  
  1374.       new_m.set_kind (old.get_kind());
  1375.       new_m.set_name (old.get_name());
  1376.       new_m.set_generated_from (old);
  1377.       new_m.set_impls (sos_Method_impl_List::make (NO_OBJECT));
  1378.       new_m.set_defined_in (aux_c);
  1379.       new_m.set_is_static (old.get_is_static());
  1380.       new_m.set_is_operator (old.get_is_operator());
  1381.       new_m.set_is_predefined (old.get_is_predefined());
  1382.       new_m.set_params (new_pl);
  1383.       new_m.set_result_type (new_tn);
  1384.    }
  1385.  
  1386.    TT (cfe_M, T_LEAVE);
  1387.    return new_m;
  1388. }
  1389.  
  1390.  
  1391. LOCAL void subst_methods (sos_Method_List old,
  1392.               sos_Class_type aux_c,
  1393.               sos_Gen_param_List gpl,
  1394.               sos_Type_name_List tnl,
  1395.               sos_Schema_type_List type_decls)
  1396. {
  1397.    T_PROC ("subst_methods");
  1398.    TT (cfe_M, T_ENTER);
  1399.  
  1400.    agg_iterate (old, sos_Method old_m)
  1401.    {  if (NOT old_m.get_is_predefined())
  1402.      cfe_append_method
  1403.         (aux_c, subst_method (old_m, aux_c, gpl, tnl, type_decls));
  1404.    }
  1405.    agg_iterate_end (old, old_m);
  1406.  
  1407.    TT (cfe_M, T_LEAVE);
  1408. }
  1409.  
  1410.  
  1411. LOCAL sos_Bool must_subst_params (sos_Param_List old,
  1412.                       sos_Gen_param_List gpl,
  1413.                       sos_Type_name_List tnl,
  1414.                       sos_Schema_type_List type_decls)
  1415. {
  1416.    T_PROC ("must_subst_params");
  1417.    TT (cfe_M, T_ENTER);
  1418.  
  1419.    sos_Bool result = FALSE;
  1420.  
  1421.    agg_iterate (old, sos_Param old_p)
  1422.    {  sos_Type_name old_tn = old_p.get_type_name();
  1423.       result = must_subst_type_name (old_tn, gpl, tnl, type_decls);
  1424.       if (result) break;
  1425.    }
  1426.    agg_iterate_end (old, old_p);
  1427.  
  1428.    TT (cfe_M, T_LEAVE);
  1429.  
  1430.    return result;
  1431. }
  1432.  
  1433.  
  1434. LOCAL sos_Param_List subst_params (sos_Param_List old,
  1435.                                    sos_Gen_param_List gpl,
  1436.                                    sos_Type_name_List tnl,
  1437.                                    sos_Schema_type_List type_decls)
  1438. {
  1439.    T_PROC ("subst_params");
  1440.    TT (cfe_M, T_ENTER);
  1441.  
  1442.    sos_Param_List new_pl;
  1443.  
  1444.    if (NOT must_subst_params (old, gpl, tnl, type_decls))
  1445.       new_pl = old;
  1446.    else
  1447.    {  new_pl = sos_Param_List::create (cfe_cnt, FALSE);
  1448.       agg_iterate (old, sos_Param old_p)
  1449.       {  sos_Type_name old_tn = old_p.get_type_name();
  1450.      sos_Type_name new_tn = subst_type_name (old_tn, gpl, tnl, type_decls);
  1451. #ifdef ATT
  1452.      if (new_tn.operator==(old_tn))
  1453. #else
  1454.      if (new_tn == old_tn)
  1455. #endif
  1456.         new_pl.append (old_p);
  1457.      else
  1458.      {  sos_Param new_p = sos_Param::create (cfe_cnt);
  1459.         new_p.set_name (old_p.get_name());
  1460.         new_p.set_type_name (new_tn);
  1461.         new_p.set_default_expr (old_p.get_default_expr());
  1462.         new_p.set_is_ref (old_p.get_is_ref());
  1463.         new_pl.append (new_p);
  1464.      }
  1465.       }
  1466.       agg_iterate_end (old, old_p);
  1467.    }
  1468.  
  1469.    TT (cfe_M, T_LEAVE);
  1470.    return new_pl;
  1471. }
  1472.  
  1473.  
  1474. LOCAL sos_Bool must_subst_type_name (sos_Type_name old,
  1475.                      sos_Gen_param_List gpl,
  1476.                      sos_Type_name_List tnl,
  1477.                      sos_Schema_type_List type_decls)
  1478. {
  1479.    T_PROC ("must_subst_type_name");
  1480.    TT (cfe_M, T_ENTER);
  1481.  
  1482.    sos_Bool result;
  1483.  
  1484.    if (old.has_type (sos_Generic_instantiation_type))
  1485.    {  sos_Generic_instantiation gi = sos_Generic_instantiation::make(old);
  1486.       sos_Type_name_List old_tnl = gi.get_gen_params();
  1487.       result = must_subst_type_names (old_tnl, gpl, tnl, type_decls);
  1488.    }
  1489.    else if (old.has_type (sos_Type_with_params_type))
  1490.    {  sos_Type_with_params twp = sos_Type_with_params::make(old);
  1491.       sos_Type_name old_twpn = twp.get_type_name();
  1492.       result = must_subst_type_name (old_twpn, gpl, tnl, type_decls);
  1493.    }
  1494.    else if (old.has_type (sos_Gen_param_type))
  1495.       result = TRUE;
  1496.    else
  1497.       result = FALSE;
  1498.  
  1499.    TT (cfe_M, T_LEAVE);
  1500.  
  1501.    return result;
  1502. }
  1503.  
  1504.  
  1505. LOCAL sos_Type_name subst_type_name (sos_Type_name old,
  1506.                                      sos_Gen_param_List gpl,
  1507.                                      sos_Type_name_List tnl,
  1508.                                      sos_Schema_type_List type_decls)
  1509. {
  1510.    T_PROC ("subst_type_name");
  1511.    TT (cfe_M, T_ENTER);
  1512.  
  1513.    sos_Type_name new_tn;
  1514.  
  1515.    if (old.has_type (sos_Generic_instantiation_type))
  1516.    {  sos_Generic_instantiation gi = sos_Generic_instantiation::make(old);
  1517.       sos_Type_name_List old_tnl = gi.get_gen_params();
  1518.       sos_Type_name_List new_tnl =
  1519.      subst_type_names (old_tnl, gpl, tnl, type_decls);
  1520. #ifdef ATT
  1521.       if (new_tnl.operator==(old_tnl))
  1522. #else
  1523.       if (new_tnl == old_tnl)
  1524. #endif
  1525.      new_tn = old;
  1526.       else
  1527.       {  sos_Generic_instantiation new_gi =
  1528.         sos_Generic_instantiation::create (cfe_cnt);
  1529.      new_gi.set_gen (gi.get_gen());
  1530.      new_gi.set_gen_params (new_tnl);
  1531.      new_gi.set_instantiation (make_aux_class_type (new_gi, type_decls));
  1532.      new_tn = new_gi;
  1533.       }
  1534.    }
  1535.    else if (old.has_type (sos_Type_with_params_type))
  1536.    {  sos_Type_with_params twp = sos_Type_with_params::make(old);
  1537.       sos_Type_name old_twpn = twp.get_type_name();
  1538.       sos_Type_name new_twpn =
  1539.      subst_type_name (old_twpn, gpl, tnl, type_decls);
  1540. #ifdef ATT
  1541.       if (new_twpn.operator==(old_twpn))
  1542. #else
  1543.       if (new_twpn == old_twpn)
  1544. #endif
  1545.      new_tn = old;
  1546.       else
  1547.       {  sos_Type_with_params new_twp =
  1548.         sos_Type_with_params::create (cfe_cnt);
  1549.      new_twp.set_type_name (new_twpn);
  1550.      new_twp.set_params (twp.get_params());
  1551.      new_tn = new_twp;
  1552.       }
  1553.    }
  1554.    else if (old.has_type (sos_Gen_param_type))
  1555.       new_tn = subst_actual (sos_Gen_param::make(old), gpl, tnl);
  1556.    else
  1557.       new_tn = old;
  1558.  
  1559.    TT (cfe_M, T_LEAVE);
  1560.  
  1561.    return new_tn;
  1562. }
  1563.  
  1564.  
  1565. LOCAL sos_Bool must_subst_type_names (sos_Type_name_List old,
  1566.                       sos_Gen_param_List gpl,
  1567.                       sos_Type_name_List tnl,
  1568.                       sos_Schema_type_List type_decls)
  1569. {
  1570.    T_PROC ("must_subst_type_names");
  1571.    TT (cfe_M, T_ENTER);
  1572.  
  1573.    sos_Bool result = FALSE;
  1574.  
  1575.    agg_iterate (old, sos_Type_name old_tn)
  1576.    {  result = must_subst_type_name (old_tn, gpl, tnl, type_decls);
  1577.       if (result) break;
  1578.    }
  1579.    agg_iterate_end (old, old_tn);
  1580.  
  1581.    TT (cfe_M, T_LEAVE);
  1582.    return result;
  1583. }
  1584.  
  1585.  
  1586. LOCAL sos_Type_name_List subst_type_names (sos_Type_name_List old,
  1587.                                            sos_Gen_param_List gpl,
  1588.                                            sos_Type_name_List tnl,
  1589.                                            sos_Schema_type_List type_decls)
  1590. {
  1591.    T_PROC ("subst_type_names");
  1592.    TT (cfe_M, T_ENTER);
  1593.  
  1594.    sos_Type_name_List new_tnl;
  1595.  
  1596.    if (NOT must_subst_type_names (old, gpl, tnl, type_decls))
  1597.       new_tnl = old;
  1598.    else
  1599.    {  new_tnl = sos_Type_name_List::create (cfe_cnt, FALSE);
  1600.  
  1601.       agg_iterate (old, sos_Type_name old_tn)
  1602.       {  new_tnl.append (subst_type_name (old_tn, gpl, tnl, type_decls));
  1603.       }
  1604.       agg_iterate_end (old, old_tn);
  1605.    }
  1606.  
  1607.    TT (cfe_M, T_LEAVE);
  1608.    return new_tnl;
  1609. }
  1610.  
  1611. static sos_Schema_type *the_void_type;
  1612.  
  1613. // *************************************************************************
  1614. LOCAL sos_Schema_type cfe_get_void_type()
  1615. // *************************************************************************
  1616. {
  1617.    T_PROC ("cfe_get_void_type");
  1618.    TT (cfe_H, T_ENTER);
  1619.  
  1620.    sos_Schema_type result;
  1621.    if (the_void_type)
  1622.       result = *the_void_type;
  1623.    else
  1624.    {
  1625. #ifdef BOOT
  1626.       result = cfe_schema.lookup_type (smg_String ("void").make_String (TEMP_CONTAINER));
  1627. #else
  1628.       result = sos_Schema_type::make (void_type);
  1629. #endif
  1630.       the_void_type = new sos_Schema_type;
  1631.       *the_void_type = result;
  1632.    }
  1633.  
  1634.    TT (cfe_H, T_LEAVE);
  1635.  
  1636.    return result;
  1637. }
  1638.  
  1639. static sos_Schema_type *the_sos_Bool_type;
  1640.  
  1641. // *************************************************************************
  1642. LOCAL sos_Schema_type cfe_get_sos_Bool_type()
  1643. // *************************************************************************
  1644. {
  1645.    T_PROC ("cfe_get_sos_Bool_type");
  1646.    TT (cfe_H, T_ENTER);
  1647.  
  1648.    sos_Schema_type result;
  1649.    if (the_sos_Bool_type)
  1650.       result = *the_sos_Bool_type;
  1651.    else
  1652.    {
  1653. #ifdef BOOT
  1654.       result = cfe_schema.lookup_type (smg_String ("sos_Bool").make_String (TEMP_CONTAINER));
  1655. #else
  1656.       result = sos_Schema_type::make (sos_Bool_type);
  1657. #endif
  1658.       the_sos_Bool_type  = new sos_Schema_type;
  1659.       *the_sos_Bool_type = result;
  1660.    }
  1661.  
  1662.    TT (cfe_H, T_LEAVE);
  1663.  
  1664.    return result;
  1665. }
  1666.  
  1667. static sos_Schema_type *the_sos_Eq_kind_type;
  1668.  
  1669. // *************************************************************************
  1670. LOCAL sos_Schema_type cfe_get_sos_Eq_kind_type()
  1671. // *************************************************************************
  1672. {
  1673.    T_PROC ("cfe_get_sos_Eq_kind_type");
  1674.    TT (cfe_H, T_ENTER);
  1675.  
  1676.    sos_Schema_type result;
  1677.    
  1678.    if (the_sos_Eq_kind_type)
  1679.       result = *the_sos_Eq_kind_type;
  1680.    else
  1681.    {
  1682. #ifdef BOOT
  1683.       result = cfe_schema.lookup_type (smg_String ("sos_Eq_kind").make_String (TEMP_CONTAINER));
  1684. #else
  1685.       result = sos_Schema_type::make (sos_Eq_kind_type);
  1686. #endif
  1687.       the_sos_Eq_kind_type  = new sos_Schema_type;
  1688.       *the_sos_Eq_kind_type = result;
  1689.    }
  1690.  
  1691.    TT (cfe_H, T_LEAVE);
  1692.  
  1693.    return result;
  1694. }
  1695.  
  1696. static sos_Schema_type *the_sos_Int_type;
  1697.  
  1698. // *************************************************************************
  1699. LOCAL sos_Schema_type cfe_get_sos_Int_type()
  1700. // *************************************************************************
  1701. {
  1702.    T_PROC ("cfe_get_sos_Int_type");
  1703.    TT (cfe_H, T_ENTER);
  1704.  
  1705.    sos_Schema_type result;
  1706.    if (the_sos_Int_type)
  1707.       result = *the_sos_Int_type;
  1708.    else
  1709.    {
  1710. #ifdef BOOT
  1711.       result = cfe_schema.lookup_type (smg_String ("sos_Int").make_String (TEMP_CONTAINER));
  1712. #else
  1713.       result = sos_Schema_type::make (sos_Int_type);
  1714. #endif
  1715.       the_sos_Int_type = new sos_Schema_type;
  1716.       *the_sos_Int_type = result;
  1717.    }
  1718.  
  1719.    TT (cfe_H, T_LEAVE);
  1720.  
  1721.    return result;
  1722. }
  1723.  
  1724. static sos_Schema_type *the_container_type;
  1725.  
  1726. // *************************************************************************
  1727. LOCAL sos_Schema_type cfe_get_container_type()
  1728. // *************************************************************************
  1729. {
  1730.    T_PROC ("cfe_get_container_type");
  1731.    TT (cfe_H, T_ENTER);
  1732.  
  1733.    sos_Schema_type result;
  1734.    if (the_container_type)
  1735.       result = *the_container_type;
  1736.    else
  1737.    {
  1738. #ifdef BOOT
  1739.       result = cfe_schema.lookup_type (smg_String ("sos_Container").make_String (TEMP_CONTAINER));
  1740. #else
  1741.       result = sos_Schema_type::make (sos_Container_type);
  1742. #endif
  1743.       the_container_type  = new sos_Schema_type;
  1744.       *the_container_type = result;
  1745.    }
  1746.  
  1747.    TT (cfe_H, T_LEAVE);
  1748.  
  1749.    return result;
  1750. }
  1751.  
  1752. static sos_Schema_type *the_object_type;
  1753.  
  1754. // *************************************************************************
  1755. EXPORT sos_Schema_type cfe_get_object_type()
  1756. // *************************************************************************
  1757. {
  1758.    T_PROC ("cfe_get_object_type");
  1759.    TT (cfe_H, T_ENTER);
  1760.  
  1761.    sos_Schema_type result;
  1762.    if (the_object_type)
  1763.       result = *the_object_type;
  1764.    else
  1765.    {
  1766. #ifdef BOOT
  1767.       result = cfe_schema.lookup_type (smg_String ("sos_Object").make_String (TEMP_CONTAINER));
  1768. #else
  1769.       result = sos_Schema_type::make (sos_Object_type);
  1770. #endif
  1771.       the_object_type  = new sos_Schema_type;
  1772.       *the_object_type = result;
  1773.    }
  1774.  
  1775.    TT (cfe_H, T_LEAVE);
  1776.  
  1777.    return result;
  1778. }
  1779.